#include <linux/kernel.h>
#include "asm/delay.h"
#include "mdio.h"
#include "util.h"
#include "higmac.h"

int wait_mdio_ready(struct higmac_netdev_local *ld)
{
    int timeout_us = 1000;

    while (--timeout_us && !test_mdio_ready(ld)) {
        udelay(1);
    }

    return timeout_us;
}

// int higmac_mdio_read(struct mii_bus *bus, int phy, int reg)
int higmac_mdio_read(struct higmac_netdev_local *netdev, int phy, int reg)
{
    struct higmac_netdev_local *ld = netdev;
    int timeout = 1000;
    int val;

    if (!wait_mdio_ready(ld)) {
        return -EIO;
    }

    mdio_start_phyread(ld, phy, reg);

    while (!wait_mdio_ready(ld) && timeout-- > 0) {
        udelay(1);
    }

    if (timeout <= 0 || !test_mdio_read_data_done(ld)) {
        return -EIO;
    }

    val = mdio_get_phyread_val(ld);

    higmac_trace(2, "mdio read phy:%x, reg:%x = %x\n", phy, reg, val);

    return val;
}

int higmac_mdio_write(struct mii_bus *bus, int phy, int reg, unsigned short val)
{
    struct higmac_netdev_local *ld = bus->priv;

    if (!wait_mdio_ready(ld)) {
        return 0;
    }

    higmac_trace(2, "mdio write phy:%x, reg:%x = %x\n", phy, reg, val);

    mdio_set_phywrite_val(ld, val);
    mdio_phywrite(ld, phy, reg);

    return val;
}

int higmac_mdio_reset(struct mii_bus *bus)
{
    /* mdio clk enable? reset? */
    return 0;
}

inline int higmac_mdio_init(struct higmac_netdev_local *ld)
{
    /* clk enable? unreset? */
    return 0;
}

inline void higmac_mdio_exit(struct higmac_netdev_local *ld)
{
}

int higmac_mdiobus_driver_init(struct higmac_netdev_local *ld, char *bus_id)
{
    return 0;
}

void higmac_mdiobus_driver_exit(struct higmac_netdev_local *ld)
{
}
